package com.slmxz.tms.common.component;


import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.slmxz.tms.common.constant.SystemConstants;
import com.slmxz.tms.common.enums.TableEnum;
import com.slmxz.tms.common.util.DateUtils;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 表主键生成器
 * @Author：albert
 * @Date：2024/9/20 21:58
 */
public class PrimaryKeyGeneratorService {
    private static final ReentrantLock lock = new ReentrantLock();

    /**
     * 生成指定数据库表当天唯一的主键
     * @param tableEnum
     * @return
     */
    public static Long generateId(TableEnum tableEnum) throws Exception {
        //根据yyMMdd获取当天的日期字符串
        String localDate = DateUtils.formatLocalDate();
        //组装redis中不同数据库表递增值的key
        String tableIdKey = tableEnum.getTableName() + localDate;
        //如果在500ms内获取锁失败,则放弃继续加锁
        if (lock.tryLock(SystemConstants.TRY_LOCK_TIMEOUT, TimeUnit.MILLISECONDS)) {
            try {
                //通过redis的自增长获取递增值
                long incrVal = RedisService.incr(tableIdKey,1);
                if(incrVal == 1L){
                    //每天初次获取值的时候
                    RedisService.expire(tableIdKey,2 * 24 * 60 * 60); //当前创建主键的key只保存2天
                }
                //组合成指定数据库表当天唯一的主键
                return Long.parseLong(localDate + incrVal);
            } finally {
                lock.unlock();
            }
        }

        Assert.isNull(null,"id generate failed!");
        return null;
    }
}
